mmap maps devices and files into a program’s running memory. mprotect lets us set usage policies about memory. brk & sbrk (mostly deprecated) for controlling how big the program data is.
But syscalls are slow, and:
So instead we use malloc and free, and the C language deals with all that for us. When a program starts we’ll give it a decent chunk of memory, and it can then be increased as needed.
malloc to get arbitrary writemalloc stores headers before the allocated memory. Indicating where the previous and next chunks are.

free stores in the freed memory where the previous free memory was so that malloc can detect where the next free section is.
malloc will merge chunks if it detects many free chunks in a row, by just expanding the new chunk to be larger and include the other free chunks.
If we can overflow into these headers, we can trick free into overwriting a specific pointer. We can overwrite the bck pointer to point to the address we want to overwrite, and the fwd pointer to the value we want to set.
At most this gives us one integer arbitrary write.
We can still write to freed memory.
Freed memory will eventually get used by another part of the program.